package com.yong.activemq.topic.persistent;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.io.IOException;

public class JmsConsumerPersistentTopic {
    static final String DEFAULT_URL = "tcp://localhost:61616";
    static final String TOPIC_NAME = "topic-persistent";

    /**
     * 发布/订阅消息传递域的特点如下：
     * （1）生产者将消息发布到topic中，每个消息可以有多个消费者，属于1：N的关系
     * （2）生产者和消费者之间有时间上的相关性。订阅某个主题的消费者只能消费自它订阅之后发布的消息
     * （3）生产者生产时，topic不保存消息它是无状态的不落地，假如无人订阅就去生产，那就是一条废消息，
     * 所以，一般先启动消费者再启动生产者。
     * <p>
     * JMS规范允许客户创建持久订阅，这在一定程度上放松了时间上的相关性要求。
     * 持久订阅允许消费者消费它在未处于激活状态时发送的消息。
     * 一句话，好比我们的微信公众号订阅
     *
     * @param args
     * @throws JMSException
     */
    public static void main(String[] args) throws JMSException, IOException {

        //System.out.println("我是2号消费者");

        // 1、创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(DEFAULT_URL);

        // 2、通过连接工厂创建connection，并且启动连接
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.setClientID("l4"); // 设置订阅者
        //connection.start();

        // 3、通过connection创建session
        // 第一个参数：事务； 第二个参数：签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 4、通过session创建destination；topic
        Topic topic = session.createTopic(TOPIC_NAME);

        /*
           1、一定要先运行一次消费者，等于向MQ注册，类似我订阅了这个主题
           2、然后再运行生产者发送消息，此时，
           3、无论消费者是否在线，都会接收到，不在线的话，下次连接的时候，会把没有收过的消息都接收下来
         */
        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "remark ....");// 创建持久化的订阅

        // 启动连接
        connection.start();

        Message message = topicSubscriber.receive();
        while (null != message){
            TextMessage textMessage = (TextMessage) message;
            System.out.println("*****收到的持久化topic:"+textMessage.getText());
            message = topicSubscriber.receive();
        }


        session.close();
        connection.close();
    }
}
